#include "bsp_public.h"
#include <stdlib.h>

typdef_tick_handle driver_tick_handle[] = {
	{
		.tick_value = 1,
		.tick_task_callback = NULL
	},
	{
		.tick_value = 10,
		.tick_task_callback = NULL
	},
	{
		.tick_value = 100,
		.tick_task_callback = NULL,
	}
};

#define TICK_HANDLE_SIZE  sizeof(driver_tick_handle)/sizeof(typdef_tick_handle)

volatile uint64_t driver_tick = 0;
static uint32_t delay_us_mul = 8;

/*!
* 说明     systic初始化（默认1ms）
* 输入[1]  无
* 返回值   无
*/
static void systick_config(void) {
	SystemCoreClockUpdate();
	/* setup systick timer for 1000Hz interrupts */
	if (SysTick_Config(SystemCoreClock / 1000U)) {
		/* capture error */
		while (1) {
		}
	}
	/* configure the systick handler priority */
	NVIC_SetPriority(SysTick_IRQn, 0xFU);
}

/*!
* 说明     driver相关公共驱动初始化
* 输入[1]  无
* 返回值   无
*/
void driver_init(void) {
	rcu_periph_clock_enable(RCU_AF);
	gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);

	SystemCoreClockUpdate();
	systick_config();
	delay_us_mul = SystemCoreClock / 1000000;
}


void delay_us(uint32_t count) {
	uint32_t temp;
	SysTick->CTRL  |= SysTick_CTRL_CLKSOURCE_Msk |
	                  SysTick_CTRL_ENABLE_Msk;
	count = count * delay_us_mul;

	if (count > SysTick->LOAD ) {
		count = SysTick->LOAD ;
	}
	temp = SysTick->VAL;
	if (temp > count) {
		while (SysTick->VAL > (temp - count) && SysTick->VAL <= temp);
	} else {
		while (SysTick->VAL <= temp);
		while (SysTick->VAL > (SysTick->LOAD - (count - temp)));
	}
}

/*!
* 说明     机器周期延时
* 输入[1]  count：机器周期个数
* 返回值   无
*/
void delay_sysclk(uint32_t count) {
	uint32_t temp;
	SysTick->CTRL  |= SysTick_CTRL_CLKSOURCE_Msk |
	                  SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */

	if (count > SysTick->LOAD ) {
		count = SysTick->LOAD ;
	}
	temp = SysTick->VAL;
	if (temp > count) {
		while (SysTick->VAL > (temp - count) && SysTick->VAL <= temp);
	} else {
		while (SysTick->VAL <= temp);
		while (SysTick->VAL > (SysTick->LOAD - (count - temp)));
	}
}

/*!
* 说明     1ms延时
* 输入[1]  count：ma单位
* 返回值   无
*/
void delay_ms(uint32_t count) {
	count = count * 10;
	do {
		delay_us(100);
	} while (count--);
}

/*!
* 说明     1ms tick递增函数，在systic中断调用
* 输入[1]  无
* 返回值   无
*/
void driver_tic_inc(void) {
	driver_tick++;
	for (uint8_t i = 0; i < TICK_HANDLE_SIZE; i++) {
		if (driver_tick % driver_tick_handle[i].tick_value == 0 &&
		    driver_tick_handle[i].tick_task_callback != NULL) {
			driver_tick_handle[i].tick_task_callback();
		}
	}
}


